﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using CapturarObjetos.Nucleo;

namespace CapturarObjetos.Objetos
{
    class Tiro : ObjetoJogo
    {
        public float DirecaoFrontal { get; set; }
        public int AlcanceMaximo { get; set; }

        public float Velocidade = 2.5f;
        public float VelocidadeDeCurva = 0.025f;
        private string tipoTiro;
        private Matrix direcaoTiro;
        ClockTimer clock;

        public static List<Jogador> listaJogadores = new List<Jogador>();

        /// <summary>
        /// Create
        /// </summary>
        /// <param name="_modelo">Model do tiro que será usado.</param>
        /// <param name="Posicao_Inicial">Posição onde o tiro será iniciado de acordo com o objeto que disparou.</param>
        /// <param name="direcao">Direção que o tiro irá andar.</param>
        /// <param name="T">Contador do jogo para poder incrementar o tempo de acordo com o hit do tiro.</param>
        /// <param name="tpTiro">Tipo do tiro corrente.</param>
        public Tiro(Model _modelo, Vector3 Posicao_Inicial, Matrix direcao, ClockTimer T, String tpTiro)
            : base()
        {
            Modelo = _modelo;
            DirecaoFrontal = 0.0f;
            AlcanceMaximo = 100;
            Posicao = Posicao_Inicial;
            Escala = .02f;
            direcaoTiro = direcao;
            Ativo = true;
            clock = T;
            tipoTiro = tpTiro;
        }
        
        public void Update(GameTime gameTime, KeyboardState teclado_atual, KeyboardState teclado_anterior, MouseState mouse_atual, MouseState mouse_anterior)
        {
            AtualizarMundoEColisoes();

            if (Game1.boxChao.Intersects(ObjetoJogo.UpdateBoundingBox(this.Modelo, this.World)))
            {
                Ativo = false;
                Game1.combo = 0;
                return;
            }

            TipoTiro("cubo");
            TipoTiro("cilindro");
            if ("piramide" == this.tipoTiro && this.tipoTiro == "piramide")
            {
                TiroDefaut(2.5f, 0.025f, 2, .07f);
            }
            if ("energia" == this.tipoTiro && this.tipoTiro == "energia")
            {
                TiroDefaut(2.5f, 0.025f, 2, .02f);
            }

            foreach (ObjetoJogo obj in ObjetoJogo.listaObjetos)
            {
                obj.AtualizarMundoEColisoes();
                this.AtualizarMundoEColisoes();   
 
                if (this.CaixaColisao.Intersects(obj.CaixaColisao) && !(obj is Jogador) && !(obj is Tiro) && (obj.Ativo))
                {
                    obj.Vida -= 1;
                    this.Ativo = false;
                }
                if (obj.Vida == 0 && !(obj is Jogador) && !(obj is Tiro) && (obj.Ativo))
                {
                    if (Game1.combo < 1)
                        Game1.Pontos += (Game1.level);
                    else
                        Game1.Pontos += (Game1.level) * Game1.combo;

                    Game1.combo++;
                    if (obj is Energia)
                        Game1.addTime = true;
                    this.Ativo = false;
                    obj.Ativo = false;

                    TipoTiro("energia");
                    TipoTiro("piramide"); 

                    TestComboValue(1);
                }
            }

            //preciso testar *primeiro* se a posição futura é válida para não travar, por isso a guardo...
            Vector3 posicaoFutura = Posicao;

            Vector3 movimento = Vector3.Zero;
            movimento.Z = -1;
            Vector3 velocidade = Vector3.Transform(movimento, direcaoTiro);
            //corrijo pela escala da velocidade
            velocidade *= Velocidade;
            //agora sim esta será a nova posicao do objeto
            posicaoFutura = Posicao + velocidade;

            if (posicaoFutura.X > AlcanceMaximo)
            {
                Game1.combo = 0;
                posicaoFutura.X = AlcanceMaximo;
                Ativo = false;
            }

            if (posicaoFutura.Z > AlcanceMaximo)
            {
                Game1.combo = 0;
                posicaoFutura.Z = AlcanceMaximo;
                Ativo = false;
            }

            if (posicaoFutura.X < -AlcanceMaximo)
            {
                Game1.combo = 0;
                posicaoFutura.X = -AlcanceMaximo;
                Ativo = false;
            }

            if (posicaoFutura.Z < -AlcanceMaximo)
            {
                Game1.combo = 0;
                posicaoFutura.Z = -AlcanceMaximo;
                Ativo = false;
            }

            Posicao = posicaoFutura;
                        
        }

        private void TipoTiro(string tipo)
        {
            if (tipo == this.tipoTiro && this.tipoTiro == "energia")
            {
                clock.addTime(1/2);
            }
            if (tipo == this.tipoTiro && this.tipoTiro == "cilindro")
            {
                TiroDefaut(5, 2, 10, .07f);
            }
            if (tipo == this.tipoTiro && this.tipoTiro == "cubo")
            {
                TiroDefaut(2.5f, 0.025f, 2, .2f);
            }
            if (tipo == this.tipoTiro && this.tipoTiro == "piramide")
            {
               Game1.Pontos += 1;
            }
        }

        public void TiroDefaut(float vel, float velDeCurva, int _ammo, float escala)
        {
            Velocidade = vel;
            VelocidadeDeCurva = velDeCurva;
            Jogador.ammo = _ammo;
            Escala = escala;
        }


        public void TestComboValue(int number)
        {
            if (Game1.combo == 10 * number)
            {
                clock.addTime(5 * number);
                number++;
            }
            if (Game1.combo == 0)
            {
                number = 1;
            }
        }

        private bool ManterNoTabuleiro(Vector3 posicaoFutura)
        {
            if ((Math.Abs(posicaoFutura.X) > AlcanceMaximo) ||
                (Math.Abs(posicaoFutura.Z) > AlcanceMaximo))
                return false;
            return true;
        }
    }
}
